package com.xbh.Book.dao.impl;

import com.xbh.Book.utils.JDBCUtils;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;

/**
 * @program: JavaWebExer
 * @description: 父类代码，子类继承他的方法得以应用，封装了对数据库的通用操作
 * @author: 许宝华
 * @create: 2021-04-03 15:54
 */

public abstract class BaseDao {
    //使用DbUtils操作数据库
    private QueryRunner queryRunner=new QueryRunner();


    /**
     *update()方法用来执行：Insert\Update\Delete语句
     * @return 如果但会-1，说明执行失败，其他返回其他表示影响的行数
     * @author 许宝华
     * @creed: Talk is cheap,show me the code
     * @date 2021/4/3 16:03
     */
    public int update(String sql,Object...args){
        //考虑到数据库事务，使用同一个连接
        Connection connection = JDBCUtils.getConnection();
        try {
            return queryRunner.update(connection,sql,args);
        } catch (SQLException e) {
            e.printStackTrace();
            //一定要往外抛出异常，不然回滚事务时，不知道是哪的错误
            throw new RuntimeException(e);
        }
    }
    /**
     *通用的查询（任意表）返回一个JavaBean(User)的sql语句
     * @param type 返回的对象类型
     * @param sql 对应的sql语句
     * @param args sql对应的参数值
     * @return T 返回的类型的泛型
     * @author 许宝华
     * @creed: Talk is cheap,show me the code
     * @date 2021/4/3 16:14
     */
    public <T> T queryForOne(Class<T> type,String sql,Object...args){
        Connection connection = JDBCUtils.getConnection();
        try {
            //为解决事务，需要使用同一个连接
            //结果集new BeanHandler<T>(type)，用于封装表中的一条记录
            //new BeanListHandler<T>(type) ,用于封装表中的多条记录
            //new ScalarHandler(),执行返回一行一列的sql语句,
            return queryRunner.query(connection,sql,new BeanHandler<T>(type),args);
        } catch (SQLException e) {
            e.printStackTrace();
            //一定要往外抛出异常，不然回滚事务时，不知道是哪的错误
            throw new RuntimeException(e);
        }
    }
    /**
     *查询返回多个JavaBean(User)的sql语句
     * @param type
     * @param sql
     * @param args
     * @return java.util.List<T>
     * @author 许宝华
     * @creed: Talk is cheap,show me the code
     * @date 2021/4/3 16:21
     */
    public <T>List<T> queryForList(Class<T> type,String sql,Object...args){
        Connection connection = JDBCUtils.getConnection();
        try {
            return queryRunner.query(connection,sql,new BeanListHandler<T>(type),args);
        } catch (SQLException e) {
            e.printStackTrace();
            //一定要往外抛出异常，不然回滚事务时，不知道是哪的错误
            throw new RuntimeException(e);
        }
    }
    /**
     *执行返回一行一列的sql语句,例如 select COUNT(*) from 表
     * @param sql 执行的sql语句
     * @param args sql对应的参数值
     * @return java.lang.Object
     * @author 许宝华
     * @creed: Talk is cheap,show me the code
     * @date 2021/4/3 16:25
     */
    public Object queryForSingleValue(String sql,Object...args){
        Connection connection = JDBCUtils.getConnection();
        try {
            return queryRunner.query(connection,sql,new ScalarHandler(),args);
        } catch (Exception e) {
            e.printStackTrace();
            //一定要往外抛出异常，不然回滚事务时，不知道是哪的错误
            throw new RuntimeException(e);
        }

    }

}
